package com.soft.collateral.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.soft.collateral.entity.Contracts;
import com.soft.collateral.entity.Edger;
import com.soft.collateral.exception.CollateralException;
import com.soft.collateral.mapper.ContractsMapper;
import com.soft.collateral.mapper.EdgerMapper;
import com.soft.collateral.service.ContractsPDFService;
import com.soft.collateral.service.ContractsService;
import com.soft.collateral.service.FileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.soft.collateral.vo.PageQueryVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.Random;

@Service
@Slf4j
@RequiredArgsConstructor
public class ContractsServiceImpl extends ServiceImpl<ContractsMapper, Contracts> implements ContractsService {

    private final ContractsMapper contractsMapper;
    private final EdgerMapper edgerMapper;
    private final FileService fileService;
    private final ContractsPDFService contractsPDFService;

    /**
     * 分页查询合同
     * @param vo
     * @return
     */
    @Transactional(readOnly = true)
    @Override
    public Page<Contracts> page(PageQueryVO vo) {
        if (ObjectUtils.isEmpty(vo)) {
            log.warn("分页查询参数为空");
            return null;
        }

        Page<Contracts> page = Page.of(vo.getCurrentPage(), vo.getPageSize());
        LambdaQueryWrapper<Contracts> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasLength(vo.getQueryString())) {
            wrapper.like(Contracts::getContractNumber, vo.getQueryString())
                    .or()
                    .like(Contracts::getSigningDate, vo.getQueryString());
        }

        return contractsMapper.selectPage(page, wrapper);
    }

    /**
     * 新增合同，同时生成并上传PDF
     * @param contracts
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveContracts(Contracts contracts) {
        // 1. 生成合同编号
        String contractNumber = generateContractNumber();
        contracts.setContractNumber(contractNumber);
        contracts.setSigningDate(LocalDate.now());

        // 2. 生成并上传PDF
        String pdfUrl = generateAndUploadPdf(contracts);
        contracts.setContractsPdf(pdfUrl);

        // 3. 保存合同
        boolean saved = saveContractToDatabase(contracts);

        // 4. 更新关联台账
        if (saved) {
            updateRelatedEdger(contracts);
        }

        return saved;
    }

    /**
     * 根据id删除合同，并且解绑台账
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Integer id) {
        Contracts contract = getById(id);
        if (contract == null) {
            log.warn("未找到ID为{}的合同", id);
            return false;
        }

        unbindRelatedEdger(contract);
        return super.removeById(id);
    }

    /**
     * 生成合同编号
     * @return
     */
    private String generateContractNumber() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        String randomNum = String.format("%04d", new Random().nextInt(10000));
        return "HT-" + dateStr + "-" + randomNum;
    }

    /**
     * 生成合同PDF
     * @param contracts
     * @return
     */
    private String generateAndUploadPdf(Contracts contracts) {
        try {
            byte[] pdfBytes = contractsPDFService.generateContractPDF(contracts);
            if (pdfBytes == null || pdfBytes.length == 0) {
                throw new CollateralException("生成的PDF内容为空");
            }
            return fileService.uploadFile(pdfBytes,
                    "contract_" + contracts.getContractNumber() + ".pdf");
        } catch (IOException e) {
            log.error("合同PDF生成失败: {}", e.getMessage());
            throw new CollateralException("合同PDF生成失败"+ e);
        }
    }

    /**
     * 保存合同
     * @param contracts
     * @return
     */
    private boolean saveContractToDatabase(Contracts contracts) {
        boolean saved = save(contracts);
        if (!saved) {
            throw new CollateralException("保存合同到数据库失败");
        }
        return saved;
    }

    /**
     * 更新关联台账
     * @param contracts
     */
    private void updateRelatedEdger(Contracts contracts) {
        if (contracts.getCollateralId() == null) {
            return;
        }

        Edger edger = edgerMapper.selectOne(new LambdaQueryWrapper<Edger>()
                .eq(Edger::getCollateralId, contracts.getCollateralId()));

        if (edger != null) {
            edger.setContractsId(contracts.getId());
            edger.setUpdateTime(LocalDate.now());
            edgerMapper.updateById(edger);
            log.info("更新关联台账ID: {}", edger.getId());
        }
    }

    /**
     * 解绑关联台账
     * @param contract
     */
    private void unbindRelatedEdger(Contracts contract) {
        if (contract.getCollateralId() == null) {
            return;
        }

        Edger edger = edgerMapper.selectOne(new LambdaQueryWrapper<Edger>()
                .eq(Edger::getCollateralId, contract.getCollateralId()));

        if (edger != null && contract.getId().equals(edger.getContractsId())) {
            edger.setContractsId(null);
            edger.setUpdateTime(LocalDate.now());
            edgerMapper.updateById(edger);
            log.info("解绑台账ID: {} 的合同关联", edger.getId());
        }
    }
}